﻿import com.audiopackage.GSync;
import com.audiopackage.GSound;

class com.audiopackage.GDelay extends GSound
{
	static private var BUFFER_LENGTH: Number = 32;
	static private var DEFAULT_RATE: Number = 5;
	static private var DEFAULT_DAMP: Number = .2;
	static private var CUT_VOLUME: Number = 1;
	
	private var gSync: GSync;	
	private var source: GSound;
	
	private var damp: Number;
	private var rate: Number;
	
	private var echoes: Array;
	private var timer: Number;
	
	function GDelay( gSync: GSync, source: GSound, targetClip: MovieClip )
	{
		super( targetClip );
		
		( this.gSync = gSync ).addListener( this );
		( this.source = source ).addListener( this );
		
		attachSound( source.getLinkageId() );
		
		echoes = new Array;
		timer = 0;
		
		rate = DEFAULT_RATE;
		damp = DEFAULT_DAMP;
	}
	
	function remove( Void ): Void
	{
		gSync.removeListener( this );
		source.removeListener( this );
	}
	
	function setRate( rate: Number ): Void
	{
		if ( rate > 0 && rate < BUFFER_LENGTH ) this.rate = rate;
	}
	
	function getRate( Void ): Number
	{
		return rate;
	}
	
	function setDamp( damp: Number ): Void
	{
		if ( damp >= 0 && damp < 1 ) this.damp = damp;
	}
	
	function getDamp( Void ): Number
	{
		return damp;
	}
	
	private function onSync( delay: Number ): Void
	{
		timer++;
		timer %= BUFFER_LENGTH;
		
		var echo = echoes[ timer ];
		
		if ( echo )
		{
			setVolume( echo.volume );
			setPan( echo.pan );
			start( delay , 1 );
			delete echoes[ timer ];
		}
	}
	
	private function onStart( gSound: GSound, delay: Number ): Void
	{
		if ( gSound == source )
		{
			var vol: Number = source.getVolume();
			var pan: Number = source.getPan();
			
			var t: Number = timer;

			while( ( vol *= damp ) > CUT_VOLUME )
			{
				if ( ( t += rate ) > BUFFER_LENGTH - 1 ) t -= BUFFER_LENGTH;
				
				if ( echoes[ t ].volume > vol ) break;
				
				echoes[ t ] = { volume: vol, pan: pan };
			}
		}
	}
}
















